Source code for qtealeaves.observables.timecorrelator

# This code is part of qtealeaves.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

"""
The time correlator measures the correlation ``<A_i(t=0) B_j(t)>`` during
a time evolution. The index `i` is fixed, while `j` is running over the
system size. It cannot be used for fermionic operators.
"""

import numpy as np

from qtealeaves.tooling import QTeaLeavesError

from .tnobase import _TNObsBase

__all__ = ["TNObsTZeroCorr"]


[docs] class TNObsTZeroCorr(_TNObsBase): """ **Arguments** name : str Define a label under which we can finde the observable in the result dictionary. operator : list of two strings Identifiers/strings for the operators to be measured. The first operator is applied at `t=0`, the second at all `t` during measurements of the time evolution. site_idx : int Specify on which site the first operator should be measured on. """ def __init__(self, name, operators, site_idx): super().__init__(name) self.measurable_ansaetze = () self.operators = [operators] self.site_inds = [site_idx]
[docs] @classmethod def empty(cls): """ Documentation see :func:`_TNObsBase.empty`. """ obj = cls(None, None, None) obj.name = [] obj.operators = [] obj.site_inds = [] return obj
def __len__(self): """ Provide appropriate length method. """ return len(self.name) def __iadd__(self, other): """ Documentation see :func:`_TNObsBase.__iadd__`. """ if isinstance(other, TNObsTZeroCorr): self.name += other.name self.operators += other.operators self.site_inds += other.site_inds else: raise QTeaLeavesError("__iadd__ not defined for this type.") return self
[docs] def collect_operators(self): """ Documentation see :func:`_TNObsBase.collect_operators`. """ for elem in self.operators: yield (elem[0], "l") yield (elem[1], "r")
[docs] def read(self, fh, **kwargs): """ Read the measurements of the time correlator obsverable from fortran. **Arguments** fh : filehandle Read the information about the measurements from this filehandle. """ # First line is separator _ = fh.readline() is_meas = fh.readline().replace("\n", "").replace(" ", "") is_measured = is_meas == "T" for elem in self.name: if not is_measured: yield elem, None continue # Observable was measured realcompl = fh.readline() if "C" in realcompl: str_values_r = fh.readline() str_values_c = fh.readline() real_val = np.array(list(map(float, str_values_r.split()))) compl_val = np.array(list(map(float, str_values_c.split()))) res = real_val + 1j * compl_val yield elem, res if "R" in realcompl: str_values_r = fh.readline() res = np.array(list(map(float, str_values_r.split()))) yield elem, res
[docs] def write_results(self, fh, state_ansatz, **kwargs): """ See :func:`_TNObsBase.write_results`. """ is_measured = self.check_measurable(state_ansatz) # Write separator first fh.write("-" * 20 + "tnobstzerocorr\n") # Assignment for the linter _ = fh.write("T \n") if is_measured else fh.write("F \n") if is_measured: for name_ii in self.name: # Write column by column because this is favored # by the fortran memory corr_mat = self.results_buffer[name_ii] real_mat = np.real(corr_mat) imag_mat = np.imag(corr_mat) if np.any(np.abs(imag_mat) > 1e-12): fh.write("C\n") str_r = " ".join(list(map(str, list(real_mat[:])))) str_c = " ".join(list(map(str, list(imag_mat[:])))) fh.write(str_r + "\n") fh.write(str_c + "\n") else: fh.write("R\n") str_r = " ".join(list(map(str, list(real_mat[:])))) fh.write(str_r + "\n") self.results_buffer = {}